#include <Windows.h>
#include <d3d9.h>
#include <time.h>
#include <iostream>

using namespace std;
#pragma comment(lib,"d3d9.lib")

const string AppTitle = "Direct3D_FullScreen";

//Direct3D object
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
bool gameover = false;

#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)

bool Game_Init(HWND hwnd) {
	D3DPRESENT_PARAMETERS d3dpp;
	//Initialize Direct3D
	d3d = Direct3DCreate9(D3D_SDK_VERSION);
	if (d3d == NULL) {
		MessageBox(hwnd,"Error Initialize Direct3D","Error",MB_OK);
		return 0;
	}

	D3DDISPLAYMODE dm;
	d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dm);

	//set Direct3D
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.hDeviceWindow = hwnd;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = dm.Format;
	d3dpp.BackBufferCount = 1;
	d3dpp.BackBufferHeight = dm.Height;
	d3dpp.BackBufferWidth = dm.Width;
	d3dpp.Windowed = FALSE;

	//create Direct3D devie
	d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
	if (d3ddev == NULL) {
		MessageBox(hwnd, "Error Creating Direct3D device", "Error", MB_OK);
		return FALSE;
	}
	return TRUE;
}

void Game_Run(HWND hwnd) {
	if (!d3ddev) {
		return;
	}

	d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 125, 255), 1.0f, 0);

	if (d3ddev->BeginScene()) {
		d3ddev->EndScene();
		d3ddev->Present(NULL, NULL, NULL, NULL);
	}
	if (KEY_DOWN(VK_ESCAPE)) {
		PostMessage(hwnd, WM_DESTROY, 0, 0);
	}
}

void Game_End(HWND hwnd) {
	if (d3ddev) {
		d3ddev->Release();
		d3ddev = NULL;
	}
	if (d3d) {
		d3d->Release();
		d3d = NULL;
	}
}

LRESULT WINAPI WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
	switch (message) {
	case WM_DESTROY:
		gameover = true;
		break;
	}
	return DefWindowProc(hwnd, message, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLink, int nCmdShow) {
	WNDCLASSEX wc;
	MSG msg;
	HWND hwnd;
	memset(&wc, 0, sizeof(WNDCLASSEX));
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.lpszClassName = "MainWindowClass";
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = (WNDPROC)WinProc;
	wc.hInstance = hInstance;
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hIcon = 0;
	wc.lpszMenuName = 0;
	wc.hbrBackground = 0;
	if (!RegisterClassEx(&wc)) {
		return FALSE;
	}

	hwnd = CreateWindow(
		"MainWindowClass",
		AppTitle.c_str(),
		WS_EX_TOPMOST | WS_POPUP,
		0,0,
		640, 480,
		(HWND)NULL,
		(HMENU)NULL,
		hInstance,
		(LPVOID)NULL);

	if (hwnd == 0) {
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	if (!Game_Init(hwnd)) {
		return 0;
	}

	while (!gameover) {
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		Game_Run(hwnd);
	}
	Game_End(hwnd);
	return msg.wParam;
}